package com.parsechina.hpush.broker.internal;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.mqtt.MqttQoS;

import java.io.Serializable;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author linfeng
 * @since 2016/12/20
 */
public class StoredMessage implements Serializable {
    private static final long serialVersionUID = 5048876388755668674L;
    private final MqttQoS qos;
    private final byte[] payload;
    private final String topic;
    private boolean retained;
    private String clientId;
    /**
     * Optional attribute, available only fo QoS 1 and 2
     */
    private Integer messageId;
    private MessageGUID guid;
    private final AtomicInteger referenceCounter = new AtomicInteger(0);
    private boolean storage = false;

    public StoredMessage(byte[] message, MqttQoS qos, String topic) {
        this.qos = qos;
        payload = message;
        this.topic = topic;
    }

    public StoredMessage(MessageGUID guid, Integer messageId, String clientId, String topic, boolean retained, MqttQoS qos, int count, byte[] payload) {
        this.guid = guid;
        this.messageId = messageId;
        this.clientId = clientId;
        this.retained = retained;
        this.topic = topic;
        this.qos = qos;
        this.payload = payload;
        this.referenceCounter.set(count);
    }

    public StoredMessage cloneMessage() {
        return new StoredMessage(this.guid, messageId, clientId, topic, retained, qos, getReferenceCounter(), payload);
    }

    public MqttQoS getQos() {
        return qos;
    }

    public ByteBuf getPayload() {

        ByteBuf byteBuf = Unpooled.buffer(8);
        byteBuf.writeBytes(payload);

        return byteBuf;
    }

    public String getTopic() {
        return topic;
    }

    public void setGuid(MessageGUID guid) {
        this.guid = guid;
    }

    public MessageGUID getGuid() {
        return guid;
    }

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public void setMessageID(Integer messageId) {
        this.messageId = messageId;
    }

    public Integer getMessageID() {
        return messageId;
    }

    public ByteBuf getMessage() {
        return Unpooled.wrappedBuffer(payload);
    }

    public void setRetained(boolean retained) {
        this.retained = retained;
    }

    public boolean isRetained() {
        return retained;
    }

    public void incReferenceCounter() {
        referenceCounter.incrementAndGet();
    }

    public void decReferenceCounter() {
        referenceCounter.decrementAndGet();
    }

    public int getReferenceCounter() {
        return referenceCounter.get();
    }

    public boolean isEmptyPayload() {
        return payload.length <= 0;
    }

    public byte[] getPayloadBytes() {
        return payload;
    }

    public boolean isStorage() {
        return storage;
    }

    public void setStorage(boolean storage) {
        this.storage = storage;
    }

    @Override
    public String toString() {
        return "PublishEvent{" +
                "messageId=" + messageId +
                ", clientId='" + clientId + '\'' +
                ", retain=" + retained +
                ", qos=" + qos +
                ", topic='" + topic + '\'' +
                '}';
    }
}
